package com.boboPlanet.comm.sensitive;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Objects;

/**
 * @Description: TODO 序列化器
 * @Author: mis_wu
 * @Date: 2023/7/18
 * @Company planet
 * <a href="https://blog.csdn.net/qq_36737803/article/details/122366043">...</a>
 **/
@AllArgsConstructor
@NoArgsConstructor
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {


    private SensitiveTypeEnum sensitiveType;

    private Integer prefixNoMaskLen;

    private Integer suffixNoMaskLen;

    private String symbol;


    @Override
    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
        if (StrUtil.isEmpty(value)) {
            value = null;
        }
        if (null != sensitiveType) {
            switch (sensitiveType) {
                case NO_MARK:
                    break;
                case CUSTOMER:
                    jsonGenerator.writeString(SensitiveUtil.desValue(value, prefixNoMaskLen, suffixNoMaskLen, symbol));
                    break;
                case NAME:
                    jsonGenerator.writeString(SensitiveUtil.hideChineseName(value));
                    break;
                case ID_CARD:
                    jsonGenerator.writeString(SensitiveUtil.hideIDCard(value));
                    break;
                case PHONE:
                    jsonGenerator.writeString(SensitiveUtil.hidePhone(value));
                    break;
                case EMAIL:
                    jsonGenerator.writeString(SensitiveUtil.hideEmail(value));
                    break;
                default:
                    throw new IllegalArgumentException("unknown sensitive type enum " + sensitiveType);
            }
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (null != beanProperty) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                SensitiveMark mark = beanProperty.getAnnotation(SensitiveMark.class);
                if (null == mark) {
                    mark = beanProperty.getContextAnnotation(SensitiveMark.class);
                }
                if (null != mark) {
                    return new SensitiveSerializer(mark.type(), mark.prefixNoMaskLen(), mark.suffixNoMaskLen(), mark.symbol());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}
